#!/usr/bin/env python
import argparse
import sys
import socket
import random
import struct

from myTunnel_header import MyTunnel
from scapy.all import sendp, send, get_if_list, get_if_hwaddr
from scapy.all import Packet
from scapy.all import Ether, IPv6, UDP, TCP, IP

def get_if():
    ifs=get_if_list()
    iface=None # "h1-eth0"
    for i in get_if_list():
        if "eth0" in i:
            iface=i
            break;
    if not iface:
        print ("Cannot find eth0 interface")
        exit(1)
    return iface

def is_ipv6_address(addr: str) -> bool:
    """Return True if addr looks like an IPv6 address."""
    try:
        socket.inet_pton(socket.AF_INET6, addr)
        return True
    except socket.error:
        return False

def is_ipv4_address(addr: str) -> bool:
    try:
        socket.inet_pton(socket.AF_INET, addr)
        return True
    except socket.error:
        return False

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('ip_addr', type=str, help="The destination Ipv4 or Ipv6 address to use")
    parser.add_argument('--ip6_src_addr', type=str, default=None, help="The source IPv6 address to use")
    parser.add_argument('message', type=str, help="The message to include in packet")
    parser.add_argument('--dst_id', type=int, default=0,
                        help='The myTunnel dst_id to use, if unspecified then myTunnel header will not be included in packet')
    args = parser.parse_args()


    # if len(sys.argv)<3:
    #    print ('pass 2 arguments: <destination> "<message>"')
    #    exit(1)
    # 假如输入为：python3 send.py 10.0.1.1 "hello"
    # 则'send.py'为argv[0] '10.0.1.1'为argv[1] "hello"为argv[2]
    # addr = sys.argv[1]
    addr = args.ip_addr
    dst_id = args.dst_id
    iface = get_if()

    send_type = 3
    if is_ipv6_address(addr):
        send_type = 1
    elif is_ipv4_address(addr) and not dst_id:
        send_type = 2

    if send_type == 2:
        print("sending on interface %s to %s" % (iface, str(addr)))
        pkt =  Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff')
        pkt = pkt /IP(dst=addr)
        pkt = pkt /TCP(dport=1234, sport=random.randint(49152,65535)) /args.message
    elif send_type == 1:
        saddr = args.ip6_src_addr
        print("sending on interface %s to %s" % (iface, str(addr)))
        pkt =  Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff')
        pkt = pkt /IPv6(src=saddr,dst=addr)
        pkt = pkt /UDP(dport=4321, sport=1234) / args.message
    elif send_type == 3:
        print("sending on interface %s to %s" % (iface, str(addr)))
        pkt =  Ether(src=get_if_hwaddr(iface), dst='ff:ff:ff:ff:ff:ff')
        pkt = pkt / MyTunnel(dst_id=dst_id) / IP(dst=addr)
        pkt = pkt / TCP(dport=1234, sport=random.randint(49152,65535)) /args.message
    pkt.show2()
    sendp(pkt, iface=iface, verbose=False)

if __name__ == '__main__':
    main()
